﻿using System.ComponentModel.Design;

namespace ICeFramework.Win.UI.Design.Util
{
    #region public delegate object TransactionAwareParammedMethod(IDesignerHost host, object parameter)
    /// <summary>
    /// 
    /// </summary>
    /// <param name="host"></param>
    /// <param name="parameter"></param>
    public delegate object TransactionAwareParammedMethod(IDesignerHost host, object parameter);
    #endregion

    public abstract class TransactionUtil
    {
        #region public static object DoInTransaction( IDesignerHost host, string transactionName, TransactionAwareParammedMethod method, object parameter)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="host"></param>
        /// <param name="transactionName"></param>
        /// <param name="method"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static object DoInTransaction(
            IDesignerHost host,
            string transactionName,
            TransactionAwareParammedMethod method,
            object parameter)
        {
            DesignerTransaction transaction = null;
            object retVal = null;

            try
            {
                transaction = host.CreateTransaction(transactionName);
                retVal = method(host, parameter);      // do the task polymorphically
            }
            catch (CheckoutException ex)	// something has gone wrong with transaction creation
            {
                if (ex != CheckoutException.Canceled)
                {
                    throw ex;
                }
            }
            catch
            {
                if (transaction != null)
                {
                    transaction.Cancel();
                    transaction = null;	// the transaction won't commit in the finally block
                }

                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Commit();
                }
            }

            return retVal;
        }
        #endregion
    }
}
